#include "dominion.h"
#include "dominion_helpers.h"
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include "rngs.h"

// set NOISY_TEST to 0 to remove printfs from output
#define NOISY_TEST 1

int main() {
	int i;
	int seed = 1000;
	int numPlayer = 2;
	int maxBonus = 10;
	int p, r, handCount;
	int bonus;
	int score;
	int k[10] = {adventurer, council_room, feast, gardens, mine
	             , remodel, smithy, village, baron, great_hall};
	struct gameState G;
	int maxHandCount = 5;

	int curses[MAX_HAND];
	int estates[MAX_HAND];
	int provinces[MAX_HAND];
	int gardenss[MAX_HAND];
	for (i = 0; i < MAX_HAND; i++)
		{
			curses[i] = curse;
			estates[i] = estate;
			provinces[i] = province;
			gardenss[i] = gardens;
		}

	printf ("TESTING scoreFor():\n");
	for (p = 0; p < numPlayer; p++)
		{
			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d curse card(s) in hand\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = handCount;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = 0;

			memcpy(G.hand[p], curses, sizeof(int) * handCount); // set all the cards in hand to curses
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * -1);
#endif
			assert(score == handCount * -1); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d curse card(s) in discard\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = 0;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = handCount;

			memcpy(G.discard[p], curses, sizeof(int) * handCount); // set all the cards in hand to curses
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * -1);
#endif
			assert(score == handCount * -1); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d curse card(s) in deck\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = 0;                 // set the number of cards on hand
			G.deckCount[p] = handCount;
			G.discardCount[p] = 0;

			memcpy(G.deck[p], curses, sizeof(int) * handCount); // set all the cards in hand to curses
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * -1);
#endif
			assert(score == handCount * -1); // check if the score is correct
			}
		}

	for (p = 0; p < numPlayer; p++)
		{
			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d estate card(s) in hand\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = handCount;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = 0;

			memcpy(G.hand[p], estates, sizeof(int) * handCount); // set all the cards in hand to estates
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * 1);
#endif
			assert(score == handCount * 1); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d estate card(s) in discard\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = 0;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = handCount;

			memcpy(G.discard[p], estates, sizeof(int) * handCount); // set all the cards in hand to estates
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * 1);
#endif
			assert(score == handCount * 1); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d estate card(s) in deck\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = 0;                 // set the number of cards on hand
			G.deckCount[p] = handCount;
			G.discardCount[p] = 0;

			memcpy(G.deck[p], estates, sizeof(int) * handCount); // set all the cards in hand to estates
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * 1);
#endif
			assert(score == handCount * 1); // check if the score is correct
			}
		}

	for (p = 0; p < numPlayer; p++)
		{
			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d province card(s) in hand\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = handCount;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = 0;

			memcpy(G.hand[p], provinces, sizeof(int) * handCount); // set all the cards in hand to provinces
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * 6);
#endif
			assert(score == handCount * 6); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d province card(s) in discard\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = 0;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = handCount;

			memcpy(G.discard[p], provinces, sizeof(int) * handCount); // set all the cards in hand to provinces
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * 6);
#endif
			assert(score == handCount * 6); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d province card(s) in deck\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.deckCount[p] = handCount;                 // set the number of cards on hand
			G.handCount[p] = 0;
			G.discardCount[p] = 0;

			memcpy(G.deck[p], provinces, sizeof(int) * handCount); // set all the cards in hand to provinces
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, handCount * 6);
#endif
			assert(score == handCount * 6); // check if the score is correct
			}
		}

	for (p = 0; p < numPlayer; p++)
		{
			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d gardens card(s) in hand\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.handCount[p] = handCount;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.discardCount[p] = 0;
			memcpy(G.hand[p], gardenss, sizeof(int) * handCount); // set all the cards in hand to gardens
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, (handCount / 10) * handCount);
#endif
			assert(score == (handCount / 10) * handCount); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d gardens card(s) in discard\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.discardCount[p] = handCount;                 // set the number of cards on hand
			G.deckCount[p] = 0;
			G.handCount[p] = 0;
			memcpy(G.discard[p], gardenss, sizeof(int) * handCount); // set all the cards in hand to gardens
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, (handCount / 10) * handCount);
#endif
			assert(score == (handCount / 10) * handCount); // check if the score is correct
			}

			for (handCount = 0; handCount < MAX_HAND; handCount++) {
#if (NOISY_TEST == 1)
			printf("Test player %d with %d gardens card(s) in deck\n", p, handCount);
#endif
			memset(&G, 23, sizeof(struct gameState));   // clear the game state
			r = initializeGame(numPlayer, k, seed, &G); // initialize a new game
			G.deckCount[p] = handCount;                 // set the number of cards on hand
			G.handCount[p] = 0;
			G.discardCount[p] = 0;
			memcpy(G.deck[p], gardenss, sizeof(int) * handCount); // set all the cards in hand to gardens
			score = scoreFor(p, &G);
#if (NOISY_TEST == 1)
			printf("score = %d, expected = %d\n", score, (handCount / 10) * handCount);
#endif
			assert(score == (handCount / 10) * handCount); // check if the score is correct
			}
		}



	printf("All tests passed!\n");

	return 0;
}
